.NET Portable TypeCast  3.1.0.4
A, easy-to-use tested, generic, portable, runtime-extensible, arbitrary type converter library
ObjectExtension[Transform].cs
Go to the documentation of this file.
1 // <copyright file=mitlicense.md url=http://lsauer.mit-license.org/ >
2 // Lo Sauer, 2013-2016
3 // </copyright>
4 // <summary> A tested, generic, portable, runtime-extensible type converter library </summary
5 // <language> C# > 6.0 </language>
6 // <version> 3.1.0.2 </version>
7 // <author> Lorenz Lo Sauer; people credited in the sources </author>
8 // <project> https://github.com/lsauer/dotnet-portable-type-cast </project>
9 namespace Core.TypeCast
10 {
11  using System;
12  using System.Reflection;
13  using System.Linq;
14  using System.Runtime.CompilerServices;
15 
16  using Core.TypeCast.Base;
17  using Core.Extensions;
18 
20  public static partial class ObjectExtension
21  {
22 
33  [MethodImpl(MethodImplOptions.AggressiveInlining)]
34  public static TOut Transform<TOut>(this TOut self, Enum functionAlias)
35  {
36  return Transform<TOut>(self: self, model: null, functionAlias: functionAlias.ToString());
37  }
38 
53  [MethodImpl(MethodImplOptions.AggressiveInlining)]
54  public static TOut Transform<TOut>(this TOut self, object model, Enum functionAlias, bool strictTypeCheck = true, bool withContext = false)
55  {
56  return Transform<TOut>(self: self, model: model, functionAlias: functionAlias.ToString(), withContext: withContext);
57  }
58 
69  [MethodImpl(MethodImplOptions.AggressiveInlining)]
70  public static TOut Transform<TOut>(this object self, Enum functionAlias)
71  {
72  return (TOut)Transform(self: self, model: null, typeBase: null, typeTo: typeof(TOut), functionAlias: functionAlias.ToString(), throwException: false);
73  }
74 
88  [MethodImpl(MethodImplOptions.AggressiveInlining)]
89  public static TOut Transform<TOut>(this object self, object model, Enum functionAlias, bool withContext = false)
90  {
91  return (TOut)Transform(self: self, model: null, typeBase: null, typeTo: typeof(TOut), functionAlias: functionAlias.ToString(), throwException: false, withContext: withContext);
92  }
93 
107  [MethodImpl(MethodImplOptions.AggressiveInlining)]
108  public static TOut Transform<TOut>(this TOut self, object model, string functionAlias = null, bool withContext = false)
109  {
110  return (TOut)Transform(self: self, model: model, typeBase: null, typeTo: typeof(TOut), functionAlias: functionAlias, throwException: false, withContext: withContext);
111  }
112 
127  [MethodImpl(MethodImplOptions.AggressiveInlining)]
128  public static TOut Transform<TBase, TOut>(this object self, object model = null, string functionAlias = null, bool strictTypeCheck = false, bool withContext = false)
129  {
130  CheckTransformTypes<TOut>(self, strictTypeCheck);
131  return (TOut)Transform<TBase, object, TOut>(self: self, model: model, functionAlias: functionAlias, strictTypeCheck: strictTypeCheck, withContext: withContext);
132  }
133 
134  [MethodImpl(MethodImplOptions.AggressiveInlining)]
135  public static TOut Transform<TBase, TIn, TOut>(this object self, object model = null, string functionAlias = null, bool strictTypeCheck = false, bool withContext = false)
136  {
137  CheckTransformTypes<TOut>(self, strictTypeCheck);
138  Converter converter = null;
139  return (TOut)Transform<TIn>(self: (TIn)self, converter: out converter, model: model, typeBase: typeof(TBase), typeTo: typeof(TOut), functionAlias: functionAlias, throwException: false, withContext: withContext);
140  }
141 
156  [MethodImpl(MethodImplOptions.AggressiveInlining)]
157  public static TOut Transform<TOut>(this TOut self, Type typeBase, object model = null, string functionAlias = null, bool withContext = false)
158  {
159  return (TOut)Transform(self: self, model: model, typeBase: null, typeTo: typeof(TOut), functionAlias: functionAlias, throwException: false, withContext: withContext);
160  }
161 
178  [MethodImpl(MethodImplOptions.AggressiveInlining)]
179  public static object Transform<TBase>(this object self, object model = null, Type typeBase = null, Type typeTo = null, string functionAlias = null, bool throwException = true, bool withContext = false)
180  {
181  return Transform(self: self, model: model, typeBase: typeof(TBase), typeTo: typeTo, functionAlias: functionAlias, throwException: throwException, withContext: withContext);
182  }
183 
199  [MethodImpl(MethodImplOptions.AggressiveInlining)]
200  public static object Transform(this object self, object model = null, Type typeBase = null, Type typeTo = null, string functionAlias = null, bool throwException = true, bool withContext = false)
201  {
202  Converter converter = null;
203  return Transform(self: self, converter: out converter, model: model, typeBase: typeBase, typeTo: typeTo, functionAlias: functionAlias, throwException: throwException, withContext: withContext);
204  }
205 
222  [MethodImpl(MethodImplOptions.AggressiveInlining)]
223  public static object Transform<TIn>(this TIn self, out Converter converter, object model = null, Type typeBase = null, Type typeTo = null, string functionAlias = null, bool throwException = true, bool withContext = false)
224  {
225  object result = null;
226  // transform should be used for similar or same types as the input type, as such if no typeTo is supplied let's use the delegate's return-type
227  typeTo = typeTo ?? typeBase?.GetTypeInfo().GetReturnParameterType();
228  if(typeof(TIn) != objectType && typeBase?.GetTypeInfo().IsInvokableWithParameters(typeTo, self.GetType(), model?.GetType()) == false)
229  {
230  throw new ConverterException(ConverterCause.DelegateArgumentWrongType);
231  }
232  GetConverterOrDefault<TIn, object>(self, out converter, out result, typeArgument: model?.GetType(), typeTo: functionAlias != null ? null : typeTo, typeBase: typeBase,
233  throwException: throwException, unboxObjectType: typeof(TIn) != objectType, attributeName: functionAlias);
234 
235  InvokeConvert(self, out result, model, throwException: throwException, converter: converter, contextInstance: (withContext ? new ConvertContext(model) : null));
236  return result;
237  }
238 
251  [MethodImpl(MethodImplOptions.AggressiveInlining)]
252  public static TOut Transform<TIn, TOut>(this TIn self, Func<TIn, TOut> converterAction, Enum addWithAttributeName, bool throwException = true)
253  {
254  return Transform<TIn, TOut>(self: self, converterAction: converterAction, addWithAttributeName: addWithAttributeName.ToString(), throwException: throwException);
255  }
256 
268  public static TOut Transform<TIn, TOut>(this TIn self, Func<TIn, TOut> converterAction, string addWithAttributeName = null, bool throwException = true)
269  {
270  TOut result = default(TOut);
271  Converter converter = null;
272  converter = ConverterCollection.CurrentInstance.Factory.Create<TIn, TOut>(converterAction);
273  var baseType = converterAction?.Target?.GetType().DeclaringType;
274 
275  if(String.IsNullOrWhiteSpace(addWithAttributeName) == false)
276  {
277  // set an alias for later filtering of transform functions
278  converter.Attribute = new ConverterAttribute(loadOnDemand: false, name: addWithAttributeName, nameSpace: baseType.Namespace);
279  ConverterCollection.CurrentInstance.Add(converter, allowDisambiguates: true);
280  }
281 
282  InvokeConvert(self: self, result: out result, defaultValue: default(TOut), throwException: throwException, converter: converter);
283 
284  return result;
285  }
286 
303  [MethodImpl(MethodImplOptions.AggressiveInlining)]
304  public static bool TryTransform(this object self, out object result, object model = null, Type typeBase = null, Type typeTo = null, string functionAlias = null, bool throwException = false, bool withContext = false)
305  {
306  Converter converter = null;
307  result = Transform(self: self, converter: out converter, model: model, typeBase: typeBase, typeTo: typeTo, functionAlias: functionAlias, throwException: throwException, withContext: withContext);
308  return converter != null;
309  }
310 
329  [MethodImpl(MethodImplOptions.AggressiveInlining)]
330  public static bool TryTransform<TIn, TOut>(this TIn self, out TOut result, object model = null, Type typeBase = null, string functionAlias = null, bool throwException = false, bool withContext = false)
331  {
332  Converter converter = null;
333  result = (TOut)Transform(self: self, converter: out converter, model: model, typeBase: typeBase, typeTo: typeof(TOut), functionAlias: functionAlias, throwException: throwException, withContext: withContext);
334  return converter != null;
335  }
336 
353  [MethodImpl(MethodImplOptions.AggressiveInlining)]
354  public static bool TryTransform<TBase, TOut>(this object self, out TOut result, object model = null, string functionAlias = null, bool throwException = false, bool withContext = false)
355  {
356  Converter converter = null;
357  result = (TOut)Transform(self: self, converter: out converter, model: model, typeBase: typeof(TBase), typeTo: typeof(TOut), functionAlias: functionAlias, throwException: throwException, withContext: withContext);
358  return converter != null;
359  }
360 
378  [MethodImpl(MethodImplOptions.AggressiveInlining)]
379  public static bool TryTransform<TBase, TIn, TOut>(this TIn self, out TOut result, object model = null, string functionAlias = null, bool throwException = false, bool withContext = false)
380  {
381  Converter converter = null;
382  result = (TOut)Transform<TIn>(self: self, converter: out converter, model: model, typeBase: typeof(TBase), typeTo: typeof(TOut), functionAlias: functionAlias, throwException: throwException, withContext: withContext);
383  return converter != null;
384  }
385 
394  [MethodImpl(MethodImplOptions.AggressiveInlining)]
395  private static void CheckTransformTypes<TOut>(object self, bool strictTypeCheck)
396  {
397  var sameOrSimilar = self.GetType().GetTypeInfo().IsSameOrSimilar<TOut>();
398  if((strictTypeCheck == true && sameOrSimilar == TypeMatch.None))
399  {
400  throw new ConverterException(ConverterCause.TransformRequiresEqualInOutTypes);
401  }
402  }
403  }
404 }
TypeMatch
An enumerating of values containing a rough 2bit classification of relationship between two types ...
Definition: TypeMatch.cs:17
ConverterCause
Contains the reasons for a ConverterException to be raised.